package com.common;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.text.InputType;
import android.text.TextUtils;
import android.widget.EditText;
import android.widget.Toast;

import java.lang.reflect.Field;

// 输入窗口
public class InputBox extends AlertDialog.Builder implements OnClickListener {
    public interface Callback {
        void onInputBoxCancel();                // 用户单击"取消"按钮事件
        void onInputBoxOK(int intValue);        // 用户单击"确定"按钮事件（返回整数值）
        void onInputBoxOK(String stringValue);  // 用户单击"确定"按钮事件（返回字符串）
    }

    private final Callback mCallback;   // 回调
    private final EditText mEditCtrl;   // 编辑框
    private int mMaxValue;              // 允许输入的最大值
    private int mMinValue;              // 允许输入的最小值
    
    /**
     * 构造方法。
     * @param callback      回调
     * @param context       设备环境
     * @param displayValue  编辑框上显示的默认值
     * @param maxValue      允许输入的最大值
     * @param minValue      允许输入的最小值
     * @param tipText       提示文字
     */
    public InputBox(Callback callback, Context context, int displayValue, int maxValue, int minValue, String tipText) {
        super(context);

        // 初始化成员
        mCallback = callback;
        mMaxValue = maxValue;
        mMinValue = minValue;

        // 设置自身不会被系统返回键取消
        super.setCancelable(false);

        // 设置提示识文字
        super.setMessage(tipText);

        // 创建编辑框
        mEditCtrl = new EditText(super.getContext());
        mEditCtrl.setFocusable(true);
        mEditCtrl.setInputType(InputType.TYPE_CLASS_NUMBER);
        mEditCtrl.setText(String.valueOf(displayValue));
        mEditCtrl.selectAll();
        super.setView(mEditCtrl);

        // 创建按钮
        super.setPositiveButton(android.R.string.ok, this);
        super.setNegativeButton(android.R.string.cancel, this);
    }
    
    /**
     * 构造方法。
     * @param callback  回调
     * @param context   设备环境
     * @param tipText   提示文字
     */
    public InputBox(Callback callback, Context context, String tipText) {
        super(context);

        mCallback = callback;

        // 设置自身不会被系统返回键取消
        super.setCancelable(false);

        // 设置提示识文字
        super.setMessage(tipText);

        // 创建编辑框
        mEditCtrl = new EditText(super.getContext());
        mEditCtrl.setFocusable(true);
        mEditCtrl.setInputType(InputType.TYPE_CLASS_TEXT);
        super.setView(mEditCtrl);

        // 创建按钮
        super.setPositiveButton(android.R.string.ok, this);
        super.setNegativeButton(android.R.string.cancel, this);
    }

    /**
     * 构造方法。
     * @param callback  回调
     * @param context   设备环境
     * @param tipTextId 提示文字的 id
     */
    public InputBox(Callback callback, Context context, int tipTextId) {
        this(callback, context, context.getString(tipTextId));
    }

    /**
     * 所有按钮的单击响应方法。
     * @param dialog        对话框
     * @param clickedButton 用户单击的按钮
     */
    @Override
    public void onClick(DialogInterface dialog, int clickedButton) {
        if (clickedButton == DialogInterface.BUTTON_NEGATIVE) {
            this.setAutoCancel(dialog, true);
            dialog.cancel();
            mCallback.onInputBoxCancel();
            return;
        }

        final String INPUT_INVALID_VALUE = "输入的内容超出了允许范围，请重新输入。";
        switch (mEditCtrl.getInputType()) {
            case InputType.TYPE_CLASS_NUMBER:
                // 检查输入的数字
                int value;
                try {
                    value = Integer.parseInt(mEditCtrl.getText().toString());
                } catch (Exception e) {
                    Toast.makeText(super.getContext(), INPUT_INVALID_VALUE, Toast.LENGTH_LONG).show();
                    mEditCtrl.requestFocus();
                    this.setAutoCancel(dialog, false);
                    return;
                }
                if (value < mMinValue || value > mMaxValue) {
                    Toast.makeText(super.getContext(), INPUT_INVALID_VALUE, Toast.LENGTH_LONG).show();
                    mEditCtrl.requestFocus();
                    this.setAutoCancel(dialog, false);
                    return;
                }
                mCallback.onInputBoxOK(value);
                break;
            case InputType.TYPE_CLASS_TEXT:
                final String text = mEditCtrl.getText().toString();
                if (TextUtils.isEmpty(text)) {
                    mCallback.onInputBoxCancel();
                } else {
                    mCallback.onInputBoxOK(text);
                }
                break;
        }

        // 关闭窗口
        this.setAutoCancel(dialog, true);
        dialog.cancel();
    }
    
    /**
     * 设置是否自动消失（自动消失是指当用户单击"确定"或"取消"按钮时消失）。
     * @param dialog        对话框
     * @param autoCancel    自动消失则为 true，否则为 false
     */
    private void setAutoCancel(DialogInterface dialog, boolean autoCancel) {
        try {
            final Class<?> superClass = dialog.getClass().getSuperclass();
            if (superClass != null) {
                final Field field = superClass.getDeclaredField("mShowing");
                field.setAccessible(true);
                field.set(dialog, autoCancel);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
